package xrand

import (
	"math"
	"math/rand/v2"
)

const (
	randomNumberIntWith64 = math.MaxInt == math.MaxInt64
)

// RangeInt 生成指定范围的随机整数
func RangeInt(min int, max int) int {
	if min > max {
		panic("RandomRangeInt: min must be less than max")
	}
	return rand.IntN(max-min+1) + min
}

// RangeInt32 生成指定范围的随机整数
func RangeInt32(min int32, max int32) int32 {
	if min > max {
		panic("RandomRangeInt32: min must be less than max")
	}
	return rand.Int32N(max-min+1) + min
}

// RangeInt64 生成指定范围的随机整数
func RangeInt64(min int64, max int64) int64 {
	if min > max {
		panic("RandomRangeInt64: min must be less than max")
	}
	return rand.Int64N(max-min+1) + min
}

// RandomRangeUint 生成指定范围的随机整数
func RandomRangeUint(min uint, max uint) uint {
	if min > max {
		panic("RandomRangeUint: min must be less than max")
	}
	return rand.UintN(max-min+1) + min
}

// RangeUint32 生成指定范围的随机整数
func RangeUint32(min uint32, max uint32) uint32 {
	if min > max {
		panic("RandomRangeUint32: min must be less than max")
	}
	return rand.Uint32N(max-min+1) + min
}

// RangeUint64 生成指定范围的随机整数
func RangeUint64(min uint64, max uint64) uint64 {
	if min > max {
		panic("RandomRangeUint64: min must be less than max")
	}
	return rand.Uint64N(max-min+1) + min
}

// RandomFloat32 生成随机浮点数[0.0,1.0).
func RandomFloat32() float32 {
	return rand.Float32()
}

// RangeFloat32 生成指定范围的随机浮点数
//
//go:noinline
func RangeFloat32(min float32, max float32) float32 {
	if min == 0 && max == 1 {
		return rand.Float32()
	} else if min == max {
		return min
	} else if min > max {
		panic("RandomRangeFloat32: min must be less than max")
	} else if min < 0 {
		panic("RandomRangeFloat32: min must be greater than 0")
	}

	minInt, maxInt := int(min), int(max)
	floatBase := minInt
	if minInt != maxInt && maxInt != 1 {
		floatBase = rand.IntN(maxInt-minInt+1) + minInt
	}
	minFloat, maxFloat := min-float32(minInt), max-float32(maxInt)
	randFloat := rand.Float32()
	for (minFloat > 0 && randFloat < minFloat) || (maxFloat > 0 && randFloat > maxFloat) {
		randFloat = rand.Float32()
	}
	randFloat = randFloat + float32(floatBase)
	if randFloat > max {
		randFloat = randFloat - 1
		if randFloat < 1 {
			return -randFloat
		}
	}
	return randFloat
}

// Float64 生成随机浮点数[0.0,1.0).
func Float64() float64 {
	return rand.Float64()
}

// RangeFloat64 生成指定范围的随机浮点数
//
//go:noinline
func RangeFloat64(min float64, max float64) float64 {
	if min == 0 && max == 1 {
		return rand.Float64()
	} else if min == max {
		return min
	} else if min > max {
		panic("RandomRangeFloat64: min must be less than max")
	} else if min < 0 {
		panic("RandomRangeFloat64: min must be greater than 0")
	}
	minInt, maxInt := int(min), int(max)
	floatBase := minInt
	if minInt != maxInt && maxInt != 1 {
		floatBase = rand.IntN(maxInt-minInt+1) + minInt
	}
	minFloat, maxFloat := min-float64(minInt), max-float64(maxInt)
	randFloat := rand.Float64()
	for (minFloat > 0 && randFloat < minFloat) || (maxFloat > 0 && randFloat > maxFloat) {
		randFloat = rand.Float64()
	}
	randFloat = randFloat + float64(floatBase)
	if randFloat > max {
		randFloat = randFloat - 1
		if randFloat < 1 {
			return -randFloat
		}
	}
	return randFloat
}

// Int 生成指定长度的随机的正整数
//   - length  32位系统长度为1-10位  math.MaxInt == math.MaxInt32 => 2147483647
//   - length  64位系统长度为1-19位  math.MaxInt == math.MaxInt64 => 9223372036854775807
func Int(length int) (number int) {
	if randomNumberIntWith64 {
		return int(Int64(length)) //64位系统
	}
	return int(Int32(length)) //32位系统
}

// Int32 生成指定长度的随机的正整数
//   - length 长度为1-10位
//   - math.MaxInt32 => 2147483647
//
//go:noinline
func Int32(length int) (number int32) {
	if length > 10 {
		length = 10
	} else if length < 1 {
		return
	}
	// 小于10Bit长度直接运算后返回
	if length < 10 {
		for i := 0; i < length; {
			bitVal := rand.Int32N(10)
			if i == 0 && bitVal == 0 {
				// 随机数字, 首位不能为0
				continue
			}
			number = number*10 + bitVal
			i++
		}
		return
	}
	// 长度为10的最大值处理
	// 2147483647  math.MaxInt32
	ok := false
	for i := 1; i <= length; i++ {
		switch i {
		case 1:
			// 首位只能是[1-2]
			number = 1 + rand.Int32N(2)
			if number < 2 {
				// 后面任意
				for j := 1; j < length; j++ {
					number = number*10 + rand.Int32N(10)
				}
				return
			}
		case 2:
			// 第2位只能是[0-1]
			if ok = _loopDecInt32(i, &number, 1); ok {
				return
			}
		case 3:
			// 第3位只能是[0-4]
			if ok = _loopDecInt32(i, &number, 4); ok {
				return
			}
		case 4:
			// 第4位只能是[0-7]
			if ok = _loopDecInt32(i, &number, 7); ok {
				return
			}
		case 5:
			// 第5位只能是[0-4]
			if ok = _loopDecInt32(i, &number, 4); ok {
				return
			}
		case 6:
			// 第6位只能是[0-8]
			if ok = _loopDecInt32(i, &number, 8); ok {
				return
			}
		case 7:
			// 第7位只能是[0-3]
			if ok = _loopDecInt32(i, &number, 3); ok {
				return
			}
		case 8:
			// 第8位只能是[0-6]
			if ok = _loopDecInt32(i, &number, 6); ok {
				return
			}
		case 9:
			// 第9位只能是[0-4]
			if ok = _loopDecInt32(i, &number, 4); ok {
				return
			}
		case 10:
			// 第10位只能是[0-7]
			number = number*10 + rand.Int32N(8)
		}
	}
	return
}

// Int64 生成指定长度的随机的正整数
//   - length 长度为1-19位, 超过19位时, 随机生成19位最大值
//   - math.MaxInt64 => 9223372036854775807
//
//go:noinline
func Int64(length int) (number int64) {
	if length > 19 {
		length = 19
	} else if length < 1 {
		return
	}
	// 小于 19 Bit 长度直接运算后返回
	if length < 19 {
		for i := 0; i < length; {
			bitVal := rand.Int64N(10)
			if i == 0 && bitVal == 0 {
				// 随机数字, 首位不能为0
				continue
			}
			number = number*10 + bitVal
			i++
		}
		return
	}

	// 长度为19 Bit 需要处理最大值边界
	// int64 : -9223372036854775808 to 9223372036854775 807
	// math.MaxInt64
	var ok bool
	for i := 1; i <= length; i++ {
		switch i {
		case 1:
			// 首位只能是[1-9]
			number = 1 + rand.Int64N(9)
			if number < 9 {
				// 后面任意
				for j := 1; j < length; j++ {
					number = number*10 + rand.Int64N(10)
				}
				return
			}
		case 2:
			// 第2位只能是[0-1]
			if ok = _loopDecInt64(i, &number, 1); ok {
				return
			}
		case 3:
			// 第3位只能是[0-1]
			if ok = _loopDecInt64(i, &number, 1); ok {
				return
			}
		case 4:
			// 第4位只能是[0-3]
			if ok = _loopDecInt64(i, &number, 3); ok {
				return
			}
		case 5:
			// 第5位只能是[0-3]
			if ok = _loopDecInt64(i, &number, 3); ok {
				return
			}
		case 6:
			// 第6位只能是[0-7]
			if ok = _loopDecInt64(i, &number, 7); ok {
				return
			}
		case 7:
			// 第7位只能是[0-2]
			if ok = _loopDecInt64(i, &number, 2); ok {
				return
			}
		case 8:
			// 第8位只能是[0]
			number = number * 10
		case 9:
			// 第9位只能是[0-3]
			if ok = _loopDecInt64(i, &number, 3); ok {
				return
			}
		case 10:
			// 第10位只能是[0-6]
			if ok = _loopDecInt64(i, &number, 6); ok {
				return
			}
		case 11:
			// 第11位只能是[0-8]
			if ok = _loopDecInt64(i, &number, 8); ok {
				return
			}
		case 12:
			// 第12位只能是[0-5]
			if ok = _loopDecInt64(i, &number, 5); ok {
				return
			}
		case 13:
			// 第13位只能是[0-4]
			if ok = _loopDecInt64(i, &number, 4); ok {
				return
			}
		case 14:
			// 第14位只能是[0-7]
			if ok = _loopDecInt64(i, &number, 7); ok {
				return
			}
		case 15:
			// 第15位只能是[0-7]
			if ok = _loopDecInt64(i, &number, 7); ok {
				return
			}
		case 16:
			// 第16位只能是[0-5]
			if ok = _loopDecInt64(i, &number, 5); ok {
				return
			}
		case 17:
			// 第17位只能是[0-8]
			if ok = _loopDecInt64(i, &number, 8); ok {
				return
			}
		case 18:
			// 第18位只能是[0]
			number = number * 10
		case 19:
			// 第19位只能是[0-7]
			number = number*10 + rand.Int64N(8)
			return
		}
	}
	return
}
func _loopDecInt32(index int, number *int32, bitMax int32) bool {
	bitVal := rand.Int32N(bitMax + 1)
	*number = (*number)*10 + bitVal
	if bitVal < bitMax {
		// 小于最大值
		// 10Bit 空位随机填充后返回
		for i := index; i < 10; i++ {
			*number = (*number)*10 + rand.Int32N(10)
		}
		return true
	}
	return false
}
func _loopDecInt64(index int, number *int64, bitMax int64) bool {
	bitVal := rand.Int64N(bitMax + 1)
	*number = *number*10 + bitVal
	if bitVal < bitMax {
		// 小于最大值
		// 19 Bit 长度空位随机填充后返回
		for i := index; i < 19; i++ {
			*number = *number*10 + rand.Int64N(10)
		}
		return true
	}
	return false
}

// Uint 生成指定长度的随机的正整数
//   - length  32位系统长度为1-10位  math.MaxUint == math.MaxUint32 => 4294967295
//   - length  64位系统长度为1-20位  math.MaxUint == math.MaxUint64 => 18446744073709551615
func Uint(length int) (number uint) {
	if randomNumberIntWith64 {
		return uint(Uint64(length)) //64位系统
	}
	return uint(Uint32(length)) //32位系统
}

// Uint32 生成指定长度的随机的正整数
//   - length 长度为1-10位, 超过10位时, 随机生成10位最大值
//   - math.MaxUint32 => 4294967295
//
//go:noinline
func Uint32(length int) (number uint32) {
	if length > 10 {
		length = 10
	} else if length < 1 {
		return 0
	}
	// 小于10Bit长度直接运算后返回
	if length < 10 {
		for i := 0; i < length; {
			bitVal := rand.Uint32N(10)
			if i == 0 && bitVal == 0 {
				// 随机数字, 首位不能为0
				continue
			}
			number = number*10 + bitVal
			i++
		}
		return
	}

	// 长度为10的最大值处理
	// uint32  0 to 4294967295 	math.MaxUint32
	var ok bool
	for i := 1; i <= length; i++ {
		switch i {
		case 1:
			// 首位只能是[1-4]
			number = 1 + rand.Uint32N(4)
			if number < 4 {
				// 后面任意
				for j := 1; j < length; j++ {
					number = number*10 + rand.Uint32N(10)
				}
				return
			}
		case 2:
			// 第2位只能是[0-1]
			if ok = _loopDecUint32(i, &number, 1); ok {
				return
			}
		case 3:
			// 第3位只能是[0-9]
			if ok = _loopDecUint32(i, &number, 9); ok {
				return
			}
		case 4:
			// 第4位只能是[0-4]
			if ok = _loopDecUint32(i, &number, 4); ok {
				return
			}
		case 5:
			// 第5位只能是[0-9]
			if ok = _loopDecUint32(i, &number, 9); ok {
				return
			}
		case 6:
			// 第6位只能是[0-6]
			if ok = _loopDecUint32(i, &number, 6); ok {
				return
			}
		case 7:
			// 第7位只能是[0-7]
			if ok = _loopDecUint32(i, &number, 7); ok {
				return
			}
		case 8:
			// 第8位只能是[0-2]
			if ok = _loopDecUint32(i, &number, 2); ok {
				return
			}
		case 9:
			// 第9位只能是[0-9]
			if ok = _loopDecUint32(i, &number, 9); ok {
				return
			}
		case 10:
			// 第10位只能是[0-5]
			number = number*10 + rand.Uint32N(6)
		}
	}
	return
}

// Uint64 生成指定长度的随机的正整数
//   - length 长度为1-20位, 超过20位时, 随机生成20位最大值
//   - math.MaxUint64 => 18446744073709551615
//
//go:noinline
func Uint64(length int) (number uint64) {
	if length > 20 {
		length = 20
	} else if length < 1 {
		return
	}
	// 小于 20 Bit 长度直接运算后返回
	if length < 20 {
		for i := 0; i < length; {
			bitVal := rand.Uint64N(10)
			if i == 0 && bitVal == 0 {
				// 随机数字, 首位不能为0
				continue
			}
			number = number*10 + bitVal
			i++
		}
		return
	}

	// 长度为 20 Bit 需要处理最大值边界
	// uint64 : 18446744073709551615
	// math.MaxUint64
	var ok bool
	for i := 1; i <= length; i++ {
		switch i {
		case 1:
			// 首位只能是[1]
			number = 1
		case 2:
			// 第2位只能是[0-8]
			if ok = _loopDecUint64(i, &number, 8); ok {
				return
			}
		case 3:
			// 第3位只能是[0-4]
			if ok = _loopDecUint64(i, &number, 4); ok {
				return
			}
		case 4:
			// 第4位只能是[0-4]
			if ok = _loopDecUint64(i, &number, 4); ok {
				return
			}
		case 5:
			// 第5位只能是[0-6]
			if ok = _loopDecUint64(i, &number, 6); ok {
				return
			}
		case 6:
			// 第6位只能是[0-7]
			if ok = _loopDecUint64(i, &number, 7); ok {
				return
			}
		case 7:
			// 第7位只能是[0-4]
			if ok = _loopDecUint64(i, &number, 4); ok {
				return
			}
		case 8:
			// 第8位只能是[0-4]
			if ok = _loopDecUint64(i, &number, 4); ok {
				return
			}
		case 9:
			// 第9位只能是[0]
			number = number * 10
		case 10:
			// 第10位只能是[0-7]
			if ok = _loopDecUint64(i, &number, 7); ok {
				return
			}
		case 11:
			// 第11位只能是[0-3]
			if ok = _loopDecUint64(i, &number, 3); ok {
				return
			}
		case 12:
			// 第12位只能是[0-7]
			if ok = _loopDecUint64(i, &number, 7); ok {
				return
			}
		case 13:
			// 第13位只能是[0]
			number = number * 10
		case 14:
			// 第14位只能是[0-9]
			if ok = _loopDecUint64(i, &number, 9); ok {
				return
			}
		case 15:
			// 第15位只能是[0-5]
			if ok = _loopDecUint64(i, &number, 5); ok {
				return
			}
		case 16:
			// 第16位只能是[0-5]
			if ok = _loopDecUint64(i, &number, 5); ok {
				return
			}
		case 17:
			// 第17位只能是[0-1]
			if ok = _loopDecUint64(i, &number, 1); ok {
				return
			}
		case 18:
			// 第18位只能是[0-6]
			if ok = _loopDecUint64(i, &number, 6); ok {
				return
			}
		case 19:
			// 第19位只能是[0-1]
			if ok = _loopDecUint64(i, &number, 1); ok {
				return
			}
		case 20:
			// 第20位只能是[0-5]
			number = number*10 + rand.Uint64N(6)
		}
	}
	return
}
func _loopDecUint32(index int, number *uint32, bitMax uint32) bool {
	bitVal := rand.Uint32N(bitMax + 1)
	*number = (*number)*10 + bitVal
	if bitVal < bitMax {
		// 小于最大值
		// 10Bit 空位随机填充后返回
		for i := index; i < 10; i++ {
			*number = (*number)*10 + rand.Uint32N(10)
		}
		return true
	}
	return false
}

func _loopDecUint64(index int, number *uint64, bitMax uint64) bool {
	bitVal := rand.Uint64N(bitMax + 1)
	*number = (*number)*10 + bitVal
	if bitVal < bitMax {
		// 小于最大值，后面随机填充后返回
		for i := index; i < 20; i++ {
			*number = (*number)*10 + rand.Uint64N(10)
		}
		return true
	}
	return false
}
